package com.hengyi.webcrawler.scheduler;

import cn.hutool.core.util.XmlUtil;
import cn.hutool.extra.template.engine.wit.WitTemplate;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hengyi.webcrawler.entity.Match;
import com.hengyi.webcrawler.pipeline.MatchPipeline;
import com.hengyi.webcrawler.processor.BeidanPreMatchBfPageProcessor;
import com.hengyi.webcrawler.processor.BeidanPreMatchBqcPageProcessor;
import com.hengyi.webcrawler.processor.BeidanPreMatchJqPageProcessor;
import com.hengyi.webcrawler.processor.BeidanPreMatchSpfPageProcessor;
import com.hengyi.webcrawler.service.IMatchService;
import com.hengyi.webcrawler.utils.CommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import us.codecraft.webmagic.Spider;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 同步比赛数据
 *
 * @author dongzp
 * @version 1.0
 * @desc
 **/
@Slf4j
@Component
public class MatchSyncScheduler {
    @Autowired
    private MatchPipeline matchPipeline;
    @Autowired
    private IMatchService matchService;

    private Long lastMatchTime;
    /**
     * 同步比赛赛前数据
     */
    @Scheduled(cron = "0 0/10 * * * *")
    public void process() throws Exception{
        // 获取今日的期号
        String gameInfo = HttpUtil.get("https://www.bjlot.com/ssm/200/html/gameinfo_his.txt");
        String qh = gameInfo.split(",")[0].substring(1);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM_dd");
        String url = qh + "_" + simpleDateFormat.format(new Date()) + ".html";
        log.info("正在爬取{}体彩数据",url);
        // 胜平负
        Spider.create(new BeidanPreMatchSpfPageProcessor()).addPipeline(matchPipeline).addUrl("https://www.bjlot.com/ssm/200/html/" + url).thread(1).run();
        Thread.sleep(5000);
        // 比分
        Spider.create(new BeidanPreMatchBfPageProcessor()).addPipeline(matchPipeline).addUrl("https://www.bjlot.com/ssm/250/html/" + url).thread(1).run();
        Thread.sleep(5000);
        // 总进球
        Spider.create(new BeidanPreMatchJqPageProcessor()).addPipeline(matchPipeline).addUrl("https://www.bjlot.com/ssm/230/html/" + url).thread(1).run();
        Thread.sleep(5000);
        // 全半场
        Spider.create(new BeidanPreMatchBqcPageProcessor()).addPipeline(matchPipeline).addUrl("https://www.bjlot.com/ssm/240/html/" + url).thread(1).run();
    }

    private Integer getYesterdayIssue(){
        LocalDate yesterday = LocalDate.now().minusDays(1);
        String date = yesterday.toString();
        log.info("昨天的日期是{}",date);
        LambdaQueryWrapper<Match> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Match::getDate,date);
        queryWrapper.last("limit 1");
        Match match = matchService.getOne(queryWrapper);
        return match != null ? match.getIssue() : null;
    }

    /**
     * 赛果同步（昨日）
     */
    @Scheduled(cron = "0 0/13 * * * *")
    public void process1() throws Exception{
        // 获取今日的期号
        String gameInfo = HttpUtil.get("https://www.bjlot.com/ssm/200/html/gameinfo_his.txt");
        Integer issueToday = Integer.parseInt(gameInfo.split(",")[0].substring(1));
        Integer issueYes = getYesterdayIssue();
        if(issueYes == null){
            return;
        }
        log.info("今天的期号是{} 昨天的期号是{}",issueToday,issueYes);

        if(issueToday.equals(issueYes)){
            // 昨天的日期
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, -1);
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM_dd");
            String url = issueYes + "_" + simpleDateFormat.format(calendar.getTime()) + ".html";
            log.info("正在爬取昨日{}体彩赛果数据",url);
            // 胜平负
            Spider.create(new BeidanPreMatchSpfPageProcessor()).addPipeline(matchPipeline).addUrl("https://www.bjlot.com/ssm/200/html/" + url).thread(1).run();
            Thread.sleep(3000);
            // 比分
            Spider.create(new BeidanPreMatchBfPageProcessor()).addPipeline(matchPipeline).addUrl("https://www.bjlot.com/ssm/250/html/" + url).thread(1).run();
            Thread.sleep(5000);
            // 总进球
            Spider.create(new BeidanPreMatchJqPageProcessor()).addPipeline(matchPipeline).addUrl("https://www.bjlot.com/ssm/230/html/" + url).thread(1).run();
            Thread.sleep(7000);
            // 全半场
            Spider.create(new BeidanPreMatchBqcPageProcessor()).addPipeline(matchPipeline).addUrl("https://www.bjlot.com/ssm/240/html/" + url).thread(1).run();
        }else {
            if(lastMatchTime != null && (System.currentTimeMillis() - lastMatchTime) < 60 * 60 * 1000){
                return;
            }
            String resultUrl = "https://www.bjlot.com/data/200ParlayGetGame_" + issueYes + ".xml";
            String gameResult = HttpUtil.get(resultUrl);
            String formatText = gameResult.substring(1).replace("<matches/>","");
            List<Match> matchList = CommonUtils.parseGameXmlData(issueYes, formatText);
            matchService.saveOrUpdateBatch(matchList);
            log.info("已爬取上期的体彩赛果数据共{}条",matchList.size());
            lastMatchTime = System.currentTimeMillis();
        }
    }

    /**
     * 同步比赛公告数据（暂不需要）
     */
//    @Scheduled(cron = "0 0 0/2 * * *")
    public void process2() throws Exception{
        // 获取最新开奖期号
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMM");
        String d = simpleDateFormat.format(new Date());
        int year = Calendar.getInstance().get(Calendar.YEAR);
        JSONObject qhData = getDataFormat("https://www.bjlot.com/data/250/control/drawnolist_"+ d +".js");
        JSONArray drawnoList = qhData.getJSONArray("drawnolist");
        JSONObject drawNo = drawnoList.getJSONObject(0);
        Integer issue = drawNo.getInteger("drawno");
        log.info("最新开奖期号：{}",issue);

        LambdaQueryWrapper<Match> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Match::getIssue,issue);
        long count = matchService.count(queryWrapper);
        if(count == 0){
            log.info("不存在{}期比赛记录",issue);
            return;
        }

        //胜平负结果、比分结果、让球结果
        JSONObject result = getDataFormat("https://www.bjlot.com/data/200/draw/"+ year +"/"+ issue +".js");
        JSONArray resultArray = result.getJSONArray("drawresult");
        Match match = null;
        for(int i = 0;i < resultArray.size();i++){
            JSONObject data = resultArray.getJSONObject(i);
            match = new Match();
            String score = data.getString("score");
            String[] scoreArr = score.split(":");
            match.setHome(data.getString("hostteam"));
            match.setAway(data.getString("guestteam"));
            match.setSpfResult(data.getString("result"));
            match.setBfResult(score);
            match.setHomeScore(Integer.parseInt(scoreArr[0]));
            match.setAwayScore(Integer.parseInt(scoreArr[1]));
            match.setIssueNum(data.getInteger("matchno"));
            match.setIssue(issue);
            match.setSellStatus(4);
            String matchId = CommonUtils.getMatchId(match);
            match.setId(CommonUtils.getMatchId(match));
            Match match2 = matchService.getById(matchId);
            if(match2 != null){
                log.info("检测到比赛存在，正在更新比赛结果");
                matchService.updateById(match);
            }else {
                log.info("检测到比赛{}-{}不存在，更新比赛结果失败",match.getHome(),match.getAway());
            }
        }

        Thread.sleep(5000);
        //总进球
        result = getDataFormat("https://www.bjlot.com/data/230/draw/"+ year +"/"+ issue +".js");
        resultArray = result.getJSONArray("drawresult");
        for(int i = 0;i < resultArray.size();i++){
            JSONObject data = resultArray.getJSONObject(i);
            match = new Match();
            match.setHome(data.getString("hostteam"));
            match.setAway(data.getString("guestteam"));
            match.setJqResult(data.getString("result"));
            match.setIssueNum(data.getInteger("matchno"));
            match.setIssue(issue);
            String matchId = CommonUtils.getMatchId(match);
            match.setId(CommonUtils.getMatchId(match));
            Match match2 = matchService.getById(matchId);
            if(match2 != null){
                log.info("检测到比赛存在，正在更新比赛结果");
                matchService.updateById(match);
            }else {
                log.info("检测到比赛{}-{}不存在，更新比赛结果失败",match.getHome(),match.getAway());
            }
        }

        Thread.sleep(5000);
        //半全场
        result = getDataFormat("https://www.bjlot.com/data/240/draw/"+ year +"/"+ issue +".js");
        resultArray = result.getJSONArray("drawresult");
        for(int i = 0;i < resultArray.size();i++){
            JSONObject data = resultArray.getJSONObject(i);
            match = new Match();
            match.setHome(data.getString("hostteam"));
            match.setAway(data.getString("guestteam"));
            match.setBqcResult(data.getString("result"));
            match.setIssueNum(data.getInteger("matchno"));
            match.setIssue(issue);
            String matchId = CommonUtils.getMatchId(match);
            match.setId(CommonUtils.getMatchId(match));
            Match match2 = matchService.getById(matchId);
            if(match2 != null){
                log.info("检测到比赛存在，正在更新比赛结果");
                matchService.updateById(match);
            }else {
                log.info("检测到比赛{}-{}不存在，更新比赛结果失败",match.getHome(),match.getAway());
            }
        }
    }

    /**
     * 获取数据并格式化
     * @param url
     * @return
     */
    private JSONObject getDataFormat(String url){
        String ret = HttpUtil.get(url);
        ret = ret.replace("jsonString=","");
        return JSON.parseObject(ret);
    }
}
